<template>
  <div>
    <el-breadcrumb separator-class="el-icon-arrow-right">
      <el-breadcrumb-item :to="{ path: '/' }">首页</el-breadcrumb-item>
      <el-breadcrumb-item>权限管理</el-breadcrumb-item>
      <el-breadcrumb-item>角色列表</el-breadcrumb-item>
    </el-breadcrumb>

    <!-- 卡片区域 -->
    <el-card>
      <!-- 第一行 -->
      <el-row>
        <el-col>
          <el-button type="primary">新增角色</el-button>
        </el-col>
      </el-row>

      <!-- 角色列表表格 -->
      <el-table :data="roleList" stripe border>
        <!-- 展开列  用来显示当前角色的三级权限 -->
        <el-table-column type="expand">
          <template slot-scope="scope">
            <el-row
              :class="['bottomBorder', ind1 === 0 ? 'topBorder' : 'vcenter']"
              v-for="(item1, ind1) in scope.row.children"
              :key="item1.id"
            >
              <!-- 第一列 一级权限 -->
              <el-col :span="5">
                <!-- 一级权限 tag -->
                <el-tag closable @close="delRightById(scope.row, item1.id)">{{
                  item1.authName
                }}</el-tag>
                <!-- 一级图标 -->
                <i class="el-icon-caret-right"></i>
              </el-col>
              <!-- 第二列 放二级权限和三级权限 -->
              <el-col :span="19">
                <!-- 放二级权限 -->
                <el-row
                  :class="[ind2 === 0 ? '' : 'topBorder', 'vcenter']"
                  v-for="(item2, ind2) in item1.children"
                  :key="item2.id"
                >
                  <el-col :span="6">
                    <el-tag
                      closable
                      @close="delRightById(scope.row, item2.id)"
                      type="danger"
                    >
                      {{ item2.authName }}
                    </el-tag>
                    <!-- 二级图标 -->
                    <i class="el-icon-caret-right"></i>
                  </el-col>
                  <el-col :span="18">
                    <!-- 放三级权限 -->
                    <el-tag
                      type="warning"
                      v-for="item3 in item2.children"
                      :key="item3.id"
                      closable
                      @close="delRightById(scope.row, item3.id)"
                      >{{ item3.authName }}</el-tag
                    >
                  </el-col>
                </el-row>
              </el-col>
            </el-row>
          </template>
        </el-table-column>
        <el-table-column prop="roleName" label="角色名"> </el-table-column>
        <el-table-column prop="roleDesc" label="说明"> </el-table-column>
        <el-table-column label="操作">
          <template slot-scope="scope">
            <el-button size="mini" type="primary" icon="el-icon-edit"
              >编辑</el-button
            >
            <el-button size="mini" type="danger" icon="el-icon-delete"
              >删除</el-button
            >
            <el-button
              @click="ShowRightDialog(scope.row)"
              size="mini"
              type="warning"
              icon="el-icon-setting"
              >分配权限</el-button
            >
          </template>
        </el-table-column>
      </el-table>
    </el-card>
    <!-- 分配权限对话框 -->
    <el-dialog title="分配权限" :visible.sync="isShowRightDialog" width="50%">
      <!-- 树形结构菜单 -->
      <el-tree
        :data="treeList"
        :props="treeProps"
        show-checkbox
        default-expand-all
        node-key="id"
        :default-checked-keys="checkedKeys"
        ref="rightTree"
      ></el-tree>
      <!-- 按钮区 -->
      <span slot="footer" class="dialog-footer">
        <el-button @click="isShowRightDialog = false">取 消</el-button>
        <el-button type="primary" @click="setRoleRights">确 定</el-button>
      </span>
    </el-dialog>
  </div>
</template>

<script>
export default {
  created() {
    this.getRolesList()
  },
  data() {
    return {
      roleId: 0, // 当前选中角色的id
      checkedKeys: [], // 树形菜单默认选中项 id
      treeProps: { label: 'authName' }, // 树形菜单的配置对象
      treeList: [], // 角色表格数据数组
      roleList: [], // 权限属性菜单数据数组
      isShowRightDialog: false // 是否显示 分配权限对话框
    }
  },
  methods: {
    async setRoleRights() {
      // 1.可以通过this.roleId 获取当前要修改权限的角色id
      // 2.获取选中的权限id 并转成分隔的字符串
      let a = this.$refs.rightTree.getCheckedKeys()
      let b = this.$refs.rightTree.getHalfCheckedKeys()
      let rightIds = [...a, ...b]
      // 3.将新权限的id以 逗号 分隔的方式组成一个字符串
      let strIds = rightIds.join(',')
      // 4.发送请求到服务器借口,更新角色权限
      let { data: resData } = await this.$http.post(
        `roles/${this.roleId}/rights`,
        {
          rids: strIds
        }
      )

      // 5.如果请求失败,则提示
      if (resData.meta.status != 200)
        return this.$message.error(resData.meta.msg)
      // 6.如果请求成功,则重新请求整个角色试图数据
      this.$message.success(resData.meta.msg)
      this.getRolesList()
      // 7.关闭当前对话框
      this.isShowRightDialog = false
    },
    closeRightDialog() {
      this.checkedKeys = []
    },
    // 获取所有三级权限 id 并加入checkedKeys数组
    // rightList  权限数组
    // 目标: 将数组元素判断一下,是否有chlidren 属性,
    //             如果有则遍历chlidren
    // 直到遇见没有chlidren 属性的元素
    getRightIds(rightList) {
      // a.遍历传入的数组
      rightList.forEach(ele => {
        // b.判断当前权限对象是否有chlidren属性
        if (ele.children) {
          return this.getRightIds(ele.children)
          //  b1.如果有 chlidren属性  则说明不是三级权限,需要递归遍历
        } else {
          //  b2. 如果没有chlidren属性  则说明是三级权限,将id直接村给checkedKeys数组
          this.checkedKeys.push(ele.id)
        }
      })
    },
    // 打开分配权限窗口 窗口(rowData  角色数据对象)
    async ShowRightDialog(rowData) {
      // 将角色id 保存到data中,等点击确认分配权限时在使用
      this.roleId = rowData.id
      this.checkedKeys = []
      // 1. 请求所有 权限列表(树形结构)
      let { data: resData } = await this.$http.get('rights/tree')
      // 2.判断是否获取成功
      if (resData.meta.status != 200) this.$message.error(resData.meta.msg)
      //3. 如果成功,则将数据设置给treeList 数组,用来渲染树形菜单
      this.treeList = resData.data

      // 将当前角色拥有的权限设置为选中状态
      // 将当前角色一级权限数组传入
      this.getRightIds(rowData.children)
      // 显示 分配权限窗口
      this.isShowRightDialog = true
    },
    // 根据id删除权限
    delRightById(roleData, rightId) {
      // a.确认是否要删除
      this.$messageBox.confirm('确认删除?', '系统提示', {
        confirmButtonText: '确定删除',
        callback: async action => {
          // b.如果点击的是取消按钮,则停止执行函数
          if (action == 'cancel') return
          // c.如果点击确认按钮,根据id请求,服务器删除权限接口
          let { data: resData } = await this.$http.delete(
            `roles/${roleData.id}/rights/${rightId}`
          )
          // d. 判断删除结果,如果失败,则提示错误
          if (resData.meta.status != 200)
            return this.$message.error(resData.meta.msg)
          // e. 如果成功,则更新试图  只更新角色权限部分
          roleData.children = resData.data
        }
      })
    },
    // 获取角色列表
    async getRolesList() {
      // 1. 异步请求 角色列表
      let { data: resData } = await this.$http.get('roles')
      // 2. 如果获取失败,显示错误提示
      if (resData.meta.status != 200)
        return this.$message.error(resData.meta.msg)
      // 3. 将返回的角色数组设置给roleList
      this.roleList = resData.data
    }
  }
}
</script>

<style lang="less" scoped>
.el-tag {
  margin: 7px;
}
.topBorder {
  border-top: 1px solid #eee;
}
.bottomBorder {
  border-top: 1px solid #eee;
}
.vcenter {
  display: flex;
  align-items: center;
}
</style>
